package com.ruoyi.web.xxj.service.impl;

import java.util.Date;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.WechatUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.web.xxj.config.WechatConfig;
import com.ruoyi.web.xxj.domain.pojo.WeChatReq;
import com.ruoyi.web.xxj.domain.pojo.WxPayV3Bean;
import com.ruoyi.web.xxj.domain.vo.WechatResp;
import com.ruoyi.web.xxj.service.IWechatUserService;
import com.ruoyi.web.xxj.service.IWxloginService;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class WxloginServiceImpl implements IWxloginService {

    @Autowired
    private IWechatUserService wechatUserService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private TokenService tokenService;

    @Override
    @Transactional
    public AjaxResult wxLogin(WeChatReq weChatReq) {

        // 调用微信认证接口，获取 session_key 和 openid 等信息
    	ResponseEntity<String> responseEntity;
        try {
            responseEntity = getWechatBaseInfo(weChatReq.getJscode());
            String result = responseEntity.getBody();
            if (StringUtils.isNotEmpty(result)) {
            	JSONObject jsonObject = JSON.parseObject(result);
            	log.info("jsonObject:",jsonObject.toString());
		        String openId = jsonObject.getString("openid");
		        log.info("wechat login openId={}", openId);
		        String sessionKey = jsonObject.getString("session_key");
		        if (StringUtils.isNotEmpty(openId)  && StringUtils.isNotEmpty(sessionKey)) {
		        	WechatUser user = wechatUserService.selectWechatUserByOpenid(openId);
		        	if (Objects.isNull(user)) {
		        		user = new WechatUser();
		        		user.setOpenid(openId);
		        		user.setNickname(weChatReq.getNickName());
		        		user.setAvatarUrl(weChatReq.getAvatarUrl());
		        		user.setCreateBy("mini");
		        		user.setCreateTime(new Date());
		        		user.setUpdateBy("mini");
		                user.setUpdateTime(new Date());
		                wechatUserService.insertWechatUser(user);
		            }else {
		            	user.setNickname(weChatReq.getNickName());
		        		user.setAvatarUrl(weChatReq.getAvatarUrl());
		        		user.setUpdateBy("mini");
		                user.setUpdateTime(new Date());
		                wechatUserService.updateWechatUser(user);
					}
		            WechatResp resp = new WechatResp();
		            resp.setJscode(weChatReq.getJscode());
		            resp.setCode(weChatReq.getCode());
		            resp.setSessionKey(sessionKey);
		            resp.setOpenId(openId);
		            JSONObject res = new JSONObject();

		         // 生成令牌
		            LoginUser loginUser = new LoginUser(user);
		            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(openId, sessionKey);
		            authenticationToken.setDetails(loginUser);
		            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
		            // 生成token
		            String token = tokenService.createToken(loginUser);

		            res.put(Constants.TOKEN, token);
		            return AjaxResult.success().put("data", res);
		        }else {
		        	log.error("=====wechat login failed!");
	                return AjaxResult.error("openId和sessionKey不能为空，登录失败！");
				}
            }
        } catch (Exception e) {
            String msg = "接口异常";
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return AjaxResult.error(msg);
        }
		return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResponseEntity<String> getWechatBaseInfo(String code) throws JsonProcessingException {
        // 调用微信认证接口，获取 session_key 和 openid 等信息
    	String loginUrl = WechatConfig.GET_AUTH_URL + "?" + "appid=" + WechatConfig.APP_ID 
	        	+ "&secret=" + WechatConfig.SECRET + "&js_code=" + code + "&grant_type=" + WechatConfig.GRANT_TYPE;
	    ResponseEntity<String> responseEntity = restTemplate.getForEntity(loginUrl, String.class);
        return responseEntity;
    }

	@Override
	public AjaxResult getPhoneNo(String code) {
		String token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"
        		+ "&appid=%s&secret=%s", WechatConfig.APP_ID, WechatConfig.SECRET);
        HttpResponse response = HttpRequest.get(token_url).execute();
        JSONObject tokenJson = JSON.parseObject(response.body());
        if(!tokenJson.containsKey("access_token")){
            throw new ServiceException("微信官方修改了获取access_token令牌接口！");
        }
        String accessToken =  tokenJson.get("access_token").toString();
        //用 access_token + code 获取手机号
        JSONObject jsonCode = new JSONObject();
        jsonCode.put("code",code);
        String resPhone = HttpUtil.post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken, jsonCode.toString());
        
        if(StringUtils.isEmpty(resPhone) || !resPhone.contains("phone_info") ||  !resPhone.contains("phoneNumber")){
            throw new ServiceException("微信官方修改了小程序获取用户手机号码相关接口！");
        }
        JSONObject resPhoneInfo = JSON.parseObject(resPhone);
        JSONObject phoneInfo=resPhoneInfo.getJSONObject("phone_info");
        String purePhoneNumber = phoneInfo.get("purePhoneNumber").toString();
        String phoneNumber = phoneInfo.get("phoneNumber").toString();
        purePhoneNumber = StringUtils.isNotEmpty(purePhoneNumber)?purePhoneNumber:phoneNumber;
        if (StringUtils.isNotEmpty(purePhoneNumber)) {
        	WechatUser wechatUser = wechatUserService.selectWechatUserById(SecurityUtils.getLoginUser().getWechatUser().getId());
        	wechatUser.setPhonenumber(purePhoneNumber);
        	wechatUserService.updateWechatUser(wechatUser);
        	return AjaxResult.success(purePhoneNumber);
		}else {
			return AjaxResult.error("获取手机号失败！");
		}
	}

}
